#pragma once
#include "common.h"
#include "trace.h"

typedef struct {
    OP *op;
    bool valid;
    bool ebreak;
    int latency;
} pipeline_latch;

typedef struct
{
    bool valid;
} RegEntry;


class Pipeline {
private:
    void FetchStage();
    pipeline_latch IFID;
    void DecodeStage();
    pipeline_latch IDEX;
    void ExecuteStage();
    pipeline_latch EXMEM;
    void MemoryStage();
    pipeline_latch MEMWB;
    void WritebackStage();

    int op_latency[NUM_OP];
    void init_op_latency();

    uint64_t op_cnt[NUM_OP];

    RegEntry regfile[32];
    void init_regfile();

    word_t pc = 0x80000000;
    word_t cycle = 0;

    uint64_t forward_stall = 0;
    uint64_t ex_stall = 0;
    uint64_t mem_stall = 0;
    uint64_t if_stall = 0;
public:
    bool sim_finish = false;
    word_t retired_instruction = 0;
    Pipeline();
    ~Pipeline();
    void run();
    void print_status();
    void print_counter();
};